package dm.ast.model.gen;

import dm.ast.DmASTNode;
import dm.ast.DmQuery;
import dm.ast.DmSelect;
import dm.ast.DmUnionQuery;
import dm.ast.model.gen.factory.BaseModelFactory;
import dm.ast.model.gen.factory.SelectModelFactory;
import dm.sql.comp.ASTComplex;
import dm.sql.comp.SQLComplexity.*;

/**
 * @author weihuixin
 * @date 2024/4/7
 * @Description
 */
public class QueryGen extends ASTGenBase{
    static int MAX_USED_TIMES =13;
    private int model_use_times;
    private int model_use_times_union = 0;
    private int model_use_times_select = 0;
    BaseModelFactory baseModelF = null;

    UnionQueryGen unionQueryGen = new UnionQueryGen();
    SelectGen selGen = new SelectGen();
    public QueryGen(){
        baseModelF = new BaseModelFactory();
        baseModelF.setTestFeatures();

        model_use_times = 0;
    }

    public DmASTNode gen(int astLevel, ComplexLevel comp){
        DmQuery dmQuery = new DmQuery();
        if(baseModelF.testFlags[BaseModelFactory.FLAG_UNION]){
            ASTComplex complex = SelectModelFactory.levelToASTComp(comp);
            unionQueryGen.baseModelF = baseModelF;
            DmUnionQuery unionQuery = (DmUnionQuery) unionQueryGen.gen(0, complex.wid_t, complex.dep_t);
            model_use_times_union++;
            dmQuery.setUnion(unionQuery);
        }else{
            DmSelect select = (DmSelect) selGen.gen(0,comp);
            setModel_use_times_select(selGen.getUseTimes());
            dmQuery.setSelect(select);
        }
        modelUseCount();
        return dmQuery;
    }

    @Override
    public DmASTNode gen(int astLevel, int wid_t, int dep_t) {
        return null;
    }
    void modelUseCount(){
        model_use_times = model_use_times_select + model_use_times_union;
        if(model_use_times >= getMaxUsedTimes()){
            model_use_times = 0;
            model_use_times_union = 0;
            selGen.setSelModels(null);
            selGen.setModels_use_times(0);
            baseModelF.setTestFeatures();
        }
    }

    public int getUseTimes(){
        return model_use_times;
    }

    private static int getMaxUsedTimes() {
        return MAX_USED_TIMES;
    }

    public void setModel_use_times_select(int model_use_times_select){
        this.model_use_times_select = model_use_times_select;
    }


}
